;        FILE = ADVUTIL/ASM   LAST MODIFIED: 05/05/85

;   VERSION 1.0 - 11/20/84
;                 INITIAL COMPLETION OF UTILITY ROUTINES.
;
;   VERSION 1.1 - 01/06/85
;                 CORRECTED ERROR IN ROUTINE "XFROBJ" WHICH DID NOT
;                 WORK PROPERLY IF TO ROOM WAS LESS THAN FROM ROOM.
;                 ADDED ROUTINE "CPYOBJ" TO COPY MOVABLE OBJEXTS
;                 FROM ONE ROOM TO ANOTHER WITHOUT CLEARING THE
;                 TO ROOM.
;   VERSION 1.2 - 09/29/85
;                 ADDED ENHANCEMENTS TO ALLOW MORE THAN 255 PICTURE
;                 OVERLAYS TO BE HANDLED BY APPENDING 0FFH (OV2) AS
;                 A PREFIX TO THE OVERLAY NUMBER.
;                 ROUTINES AFFECTED: CKDRAW
;                 ADDED MODIFICATIONS TO SUBTRACT OUT TREASURE
;                 POINTS WHEN THEY ARE REMOVED FROM THE TREASURE
;                 ROOM.  ROUTINES AFFECTED: GETOBJ, PUTOBJ

         INCLUDE ADVEQU.ASM

         INCLUDE ADVMACRO.ASM

DATA     SEGMENT PUBLIC

         EXTRN   RMOBT1:BYTE, RMOBT2:BYTE, ROOM:BYTE,   PUTTAB:BYTE
         EXTRN   PNTTAB:BYTE, POINTS:BYTE, OBJECT:BYTE, OBJCNT:BYTE
         EXTRN   EQUTAB:BYTE, NOUNNO:BYTE, VERBNO:BYTE, SCRIND:BYTE
         EXTRN   VERB:BYTE,   NOUN:BYTE,   KEYBUF:BYTE, MOVOBJ:BYTE
         EXTRN   VERBTB:BYTE, NOUNTB:BYTE, ASCSAV:WORD, TENTBL:WORD
         EXTRN   SCRTAB:WORD, ROOMTB:BYTE, ANTIMSW:BYTE
         EXTRN   MAXOBJ1:BYTE,NORMS1:BYTE, TRESRM1:BYTE
         EXTRN   ROW:BYTE,    COL:BYTE

SAVROW   DB    0
SAVCOL   DB    0

COMMA    DB    ','+80H,0

DATA     ENDS

CODE     SEGMENT PUBLIC

         ASSUME  CS:CODE,DS:DATA

         PUBLIC  PUTNRM,      PUTOBJ,      RMVIS,       XFROBJ
         PUBLIC  CLRRM,       CLROBJ,      SUPRES,      GETOBJ
         PUBLIC  HAVOBJ,      REPOBJ,      EQUOBJ,      XCHGOB
         PUBLIC  FNDOBJ,      CKOBJ,       CHGOBJ,      MAKVIS
         PUBLIC  PNTRM1,      PNTRM2,      SCNKEY,      SCNTBL
         PUBLIC  DELAY,       GIVOBJ,      LOCOBJ,      CVTCAP
         PUBLIC  MOVE,        ASCLNO,      CKDRAW,      DRAWSC
         PUBLIC  PERIOD,      PUTCMA,      CPYOBJ

         EXTRN   INDARK:NEAR

         EXTRN   DISPLY:NEAR,    CHROUT:NEAR,    SHOSCR:NEAR
         EXTRN   SHOOBJ:NEAR,    CLR_CHAR:NEAR

         DB    'ADVUTIL - V1.2  09/29/85'

;********************************************************************
;
;  PUTCMA - DISPLAY A COMMA FOLLOWED BY A SPACE AND SAVE THE ROW/COL
;           IN THE EVENT WE NEED TO REPLACE IT WITH A PERIOD.
;
;           INPUT:  NONE
;           OUTPUT: NONE
;
;********************************************************************

PUTCMA   PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         MOV   AL,ROW
         MOV   SAVROW,AL
         MOV   AL,COL
         MOV   SAVCOL,AL
         MOV   BX,OFFSET COMMA
         CALL  DISPLY
         POP   BX
         POP   AX
         RET
PUTCMA   ENDP

;********************************************************************
;
;  PERIOD - RESTORE ROW/COL TO POSITION OF LAST COMMA AND REPLACE
;           IT WITH A PERIOD.
;
;           INPUT:  NONE
;           OUTPUT: NONE
;
;********************************************************************

PERIOD   PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         MOV   AL,SAVROW
         MOV   ROW,AL
         MOV   AL,SAVCOL
         MOV   COL,AL
         CALL  CLR_CHAR
         MOV   AL,'.'
         CALL  CHROUT
         POP   BX
         POP   AX
         RET
PERIOD   ENDP

;********************************************************************
;
;  PUTNRM - PUT OBJECT IN CURRENT ROOM WITH NO POINT OR MOVED
;           LOCATION CHECKING
;
;           INPUT:  AL = OBJECT TO BE PLACED IN CURRENT ROOM
;           OUTPUT: NONE
;
;********************************************************************

PUTNRM   PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         PUSH  DI
         CMP   AL,0               ;OBJECT # ZERO NOT ALLOWED
         JE    PUTNRM_D
         CALL  PNTRM1             ;GET ROOM OFFSET IN ROOM TABLE
PUTNRM_A:
         TEST  BYTE PTR [BX],0FFH ;FIND END OF THIS ROOM ENTRY
         JE    PUTNRM_B
         INC   BX
         JMP   SHORT PUTNRM_A
PUTNRM_B:
         LEA   DI,RMOBT2          ;MOVE ALL TABLE ENTRIES DOWN
         DEC   DI
PUTNRM_C:                         ;ONE BYTE TO MAKE ROOM FOR THE
         DEC   DI
         MOV   AH,[DI]            ;NEW ROOM ENTRY
         MOV   [DI+1],AH
         CMP   DI,BX
         JNE   PUTNRM_C
         MOV   [BX],AL
PUTNRM_D:
         POP   DI                 ;RESTORE REGISTERS
         POP   BX
         POP   AX
         RET
PUTNRM   ENDP

;********************************************************************
;
;  PUTOBJ - PUT OBJECT IN CURRENT ROOM AND UPDATE POINTS BASED
;           UPON TRESRM AND PNTTAB.  ALSO CHECK IF OBJECT DROPPED
;           IN THIS ROOM SHOULD BE MOVED TO ANOTHER ROOM AND DO SO
;           IF TABLE SO INDICATES
;
;           INPUT:  AL = OBJECT TO BE PLACED IN CURRENT ROOM
;           OUTPUT: NONE
;
;********************************************************************

PUTOBJ   PROC
         PUSH  AX
         PUSH  BX
         PUSH  DI
         MOV   AH,ROOM            ;SAVE CURRENT ROOM NUMBER
         PUSH  AX
         CMP   AL,0               ;OBJECT # ZERO IS NOT ALLOWED
         JE    PUTOBJ_G
         DISABLE
         LEA   BX,PUTTAB          ;CHECK IF OBJECT SHOULD BE PUT
PUTOBJ_A:                         ;INTO ANOTHER ROOM
         TEST  BYTE PTR [BX],0FFH
         JZ    PUTOBJ_C
         CMP   AH,[BX]
         JE    PUTOBJ_B
         ADD   BX,2
         JMP   SHORT PUTOBJ_A
PUTOBJ_B:
         MOV   AH,[BX+1]          ;SUBSTITUTE NEW ROOM NUMBER
         MOV   ROOM,AH
PUTOBJ_C:
         CALL  PUTNRM             ;PUT OBJ IN THE ROOM
         MOV   AH,ROOM            ;SEE IF WE NEED TO ADD POINTS
         CMP   AH,TRESRM1
         JNE   PUTOBJ_G
         LEA   DI,PNTTAB          ;SEE IF OBJECT IS A TREASURE AND
PUTOBJ_F:                         ;IF SO ADD IN ITS'S POINT VALUE
         TEST  BYTE PTR [DI],0FFH
         JZ    PUTOBJ_G
         ADD   DI,2
         CMP   AL,[DI-2]
         JNE   PUTOBJ_F
         MOV   AL,[DI-1]
         ADD   POINTS,AL
PUTOBJ_G:
         POP   AX
         MOV   ROOM,AH
         POP   DI                 ;RESTORE REGISTERS
         POP   BX
         POP   AX
         RET
PUTOBJ   ENDP

;********************************************************************
;
;  RMVIS  - MAKE AN INVISIBLE ROOM VISIBLE
;
;           INPUT:  AL = ROOM TO BE MADE VISIBLE (INV BIT SET)
;           OUTPUT: NONE
;
;********************************************************************

RMVIS    PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         PUSH  AX
         MOV   AL,RMSIZE          ;CALC ENTRY ADDR FOR CURRENT ROOM
         MOV   BL,ROOM            ;IN THE ROOM TABLE
         DEC   BL
         MUL   BL
         LEA   BX,ROOMTB
         ADD   BX,AX
         POP   AX
         MOV   AH,RMSIZE          ;SIZE OF A TABLE ENTRY
RMVIS_A:
         CMP   AL,[BX]            ;FIND INVISIBLE ROOM AND MAKE IT
         JE    RMVIS_B            ;VISIBLE
         INC   BX
         DEC   AH
         JNZ   RMVIS_A
         JMP   SHORT RMVIS_C      ;IF NOT FOUND IN TABLE
RMVIS_B:
         AND   AL,07FH            ;RESET INVISIBLE BIT
         MOV   [BX],AL            ;PUT NEW ROOM PNTR IN TABLE
RMVIS_C:
         POP   BX                 ;RESTORE REGISTERS
         POP   AX
         RET
RMVIS    ENDP

;********************************************************************
;
;  XFROBJ - TRANSFER MOVABLE OBJECTS FROM ONE ROOM TO ANOTHER
;  CPYOBJ - TRANSFER MOVABLE OBJECTS WITHOUT CLEARING "TO" ROOM
;
;           INPUT:  AL = FROM ROOM
;                   AH = TO ROOM
;           OUTPUT: NONE
;
;********************************************************************

XFROBJ   PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         PUSH  CX
         DISABLE
         MOV   CX,AX
         MOV   AL,ROOM            ;SAVE CURRENT ROOM
         PUSH  AX
         MOV   AL,AH              ;CLEAR TO ROOM
         CALL  CLROBJ
XFROBJ_A:
         MOV   ROOM,CL            ;CALC ROOM TABLE ENTRY ADDR
         CALL  PNTRM1
XFROBJ_B:
         MOV   AL,[BX]            ;MOVE ALL MOVABLE OBJECTS
         INC   BX
         CMP   AL,0
         JE    XFROBJ_C
         CMP   AL,64
         JA    XFROBJ_B
         CALL  GETOBJ
         CMP   AL,0
         JE    XFROBJ_C
         MOV   ROOM,CH
         CALL  PUTNRM
         JMP   SHORT XFROBJ_A
XFROBJ_C:
         POP   AX                 ;RESTORE CURRENT ROOM
         MOV   ROOM,AL
         ENABLE
         POP   CX
         POP   BX
         POP   AX
         RET
CPYOBJ:
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         PUSH  CX
         DISABLE
         MOV   CX,AX
         MOV   AL,ROOM            ;SAVE CURRENT ROOM
         PUSH  AX
         JMP   SHORT XFROBJ_A
XFROBJ   ENDP

;********************************************************************
;
;  CLRRM  - REMOVE ALL OBJECTS FROM A ROOM
;
;           INPUT:  AL = ROOM TO CLEAR
;           OUTPUT: NONE
;
;********************************************************************

CLRRM    PROC
         PUSH  AX
         PUSH  BX
         DISABLE
         MOV   AH,ROOM
         MOV   ROOM,AL
         CALL  PNTRM1
CLRRM_A:
         MOV   AL,[BX]
         CMP   AL,0
         JE    CLRRM_B
         CALL  GETOBJ
         JMP   SHORT CLRRM_A
CLRRM_B:
         MOV   ROOM,AH
         ENABLE
         POP   BX
         POP   AX
         RET
CLRRM    ENDP

;********************************************************************
;
;  CLROBJ - REMOVE ALL MOVABLE OBJECTS FROM A ROOM
;
;           INPUT:  AL = ROOM TO CLEAR
;           OUTPUT: NONE
;
;********************************************************************

CLROBJ   PROC
         PUSH  AX
         PUSH  BX
         DISABLE
         MOV   AH,ROOM
         MOV   ROOM,AL
         CALL  PNTRM1
CLROBJ_A:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    CLROBJ_B
         CMP   AL,64
         JA    CLROBJ_A
         CALL  GETOBJ
         DEC   BX
         JMP   SHORT CLROBJ_A
CLROBJ_B:
         MOV   ROOM,AH
         ENABLE
         POP   BX
         POP   AX
         RET
CLROBJ   ENDP

;********************************************************************
;
;  SUPRES - SUPRESS LEADING ZEROS ON ASCII DECIMAL NUMBER
;
;           INPUT:  SI = POINTER TO FIVE DIGIT ASCII NUMBER
;           OUTPUT: NONE
;
;********************************************************************

SUPRES   PROC
         PUSH  AX
         PUSH  SI
         MOV   AH,4
SUPRES_A:
         MOV   AL,'0'
         CMP   AL,[SI]
         JNE   SUPRES_B
         MOV   AL,' '
         MOV   [SI],AL
         INC   SI
         DEC   AH
         JNZ   SUPRES_A
SUPRES_B:
         POP   SI
         POP   AX
         RET
SUPRES   ENDP

;********************************************************************
;
;  GETOBJ - GET (AND REMOVE) OBJECT FROM CURRENT ROOM
;
;           INPUT:  AL = OBJECT NUMBER TO GET
;           OUTPUT: AL = STATUS OF REQUEST
;                        IF = 0 THEN OBJECT NOT IN CURRENT ROOM
;                        IF > 0 THEN OBJECT FOUND AND REMOVED
;
;********************************************************************

GETOBJ   PROC
         PUSH  BX
         PUSH  CX
         CALL  PNTRM1
GETOBJ_A:
         TEST  BYTE PTR [BX],0FFH
         JZ    GETOBJ_C
         INC   BX
         CMP   AL,[BX-1]
         JNE   GETOBJ_A
GETOBJ_B:
         MOV   CL,[BX]
         MOV   [BX-1],CL
         INC   BX
         CMP   BX,OFFSET RMOBT2
         JB    GETOBJ_B
         PUSH  AX
         MOV   AH,ROOM
         CMP   AH,TRESRM1
         JNE   GETOBJ_F
         MOV   BX,OFFSET PNTTAB
GETOBJ_E:
         TEST  BYTE PTR [BX],0FFH
         JZ    GETOBJ_F
         INC   BX
         INC   BX
         CMP   AL,[BX-2]
         JNE   GETOBJ_E
         MOV   AH,POINTS
         SUB   AH,[BX-1]
         MOV   POINTS,AH
GETOBJ_F:
         POP   AX
         JMP   SHORT GETOBJ_D
GETOBJ_C:
         MOV   AL,0
GETOBJ_D:
         POP   CX
         POP   BX
         TEST  AL,0FFH
         RET
GETOBJ   ENDP

;********************************************************************
;
;  HAVOBJ - CHECK IF PLAYER IS CARRYING AN OBJECT
;
;           INPUT:  AL = OBJECT NUMBER TO CHECK FOR
;           OUTPUT: AL = STATUS OF REQUEST
;                        IF = 0 THEN OBJECT NOT IN INVENTORY
;                        IF > 0 THEN OBJECT FOUND IN INVENTORY
;
;********************************************************************

HAVOBJ   PROC
         PUSH  BX
         PUSH  CX
         LEA   BX,OBJECT
         MOV   CL,MAXOBJ1
HAVOBJ_A:
         CMP   AL,[BX]
         JE    HAVOBJ_B
         INC   BX
         DEC   CL
         JNZ   HAVOBJ_A
         MOV   AL,0
HAVOBJ_B:
         POP   CX
         POP   BX
         TEST  AL,0FFH
         RET
HAVOBJ   ENDP

;********************************************************************
;
;  REPOBJ - REPLACE OBJECT IN PLAYERS INVENTORY
;
;           INPUT:  AL = OBJECT NUMBER TO CHECK FOR
;                   AH = REPLACEMENT OBJECT
;           OUTPUT: NONE
;
;********************************************************************

REPOBJ   PROC
         PUSH  BX
         PUSH  CX
         LEA   BX,OBJECT
         MOV   CL,MAXOBJ1
REPOBJ_A:
         CMP   AL,[BX]
         JE    REPOBJ_B
         INC   BX
         DEC   CL
         JNZ   REPOBJ_A
         JMP   SHORT REPOBJ_C
REPOBJ_B:
         MOV   [BX],AH
         TEST  AH,0FFH
         JNZ   REPOBJ_C
         DEC   OBJCNT
REPOBJ_C:
         POP   CX
         POP   BX
         RET
REPOBJ   ENDP

;********************************************************************
;
;  EQUOBJ - CHECK FOR OBJECT NUMBERS THAT ARE EQUATED TO OTHER OBJECTS
;
;           INPUT:  [NOUNNO] = CURRENT OBJECT NUMBER
;           OUTPUT: [NOUNNO] = NEW OBJECT NUMBER
;
;********************************************************************

EQUOBJ   PROC
         PUSH  AX
         PUSH  BX
         LEA   BX,EQUTAB
EQUOBJ_A:
         INC   BX
         MOV   AL,[BX-1]
         CMP   AL,0
         JE    EQUOBJ_D
         CMP   AL,NOUNNO
         JNE   EQUOBJ_C
EQUOBJ_B:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    EQUOBJ_D
         CALL  LOCOBJ
         JZ    EQUOBJ_B
         MOV   NOUNNO,AL
         JMP   SHORT EQUOBJ_D
EQUOBJ_C:
         INC   BX
         TEST  BYTE PTR [BX-1],0FFH
         JNZ   EQUOBJ_C
         JMP   SHORT EQUOBJ_A
EQUOBJ_D:
         POP   BX
         POP   AX
         RET
EQUOBJ   ENDP

;********************************************************************
;
;  XCHGOB - EXCHANGE AN OBJECT ANYWHERE IN THE GAME
;
;           INPUT:  AL = CURRENT OBJECT NUMBER
;           OUTPUT: AH = REPLACEMENT OBJECT NUMBER
;
;********************************************************************

XCHGOB   PROC
         PUSH  CX
         DISABLE
         MOV   CL,ROOM
         MOV   CH,NORMS1
         MOV   ROOM,CH
         CALL  REPOBJ
XCHGOB_A:
         CALL  CHGOBJ
         DEC   ROOM
         JNZ   XCHGOB_A
         MOV   ROOM,CL
         ENABLE
         POP   CX
         RET
XCHGOB   ENDP

;********************************************************************
;
;  FNDOBJ - FIND AN OBJECT ANYWHERE IN THE GAME
;
;           INPUT:  AL = OBJECT TO FIND
;           OUTPUT: AL = STATUS OF REQUEST
;                        IF = 00 THEN OBJECT NOT FOUND
;                        IF = FF THEN OBJECT IS IN INVENTORY
;                        IF = NN THEN OBJECT IS IN ROOM NN
;
;********************************************************************

FNDOBJ   PROC
         PUSH  CX
         DISABLE
         MOV   CL,ROOM
         MOV   CH,NORMS1
         MOV   ROOM,CH
         MOV   CH,AL
         CALL  HAVOBJ
         JZ    FNDOBJ_A
         MOV   AL,0FFH
         JMP   SHORT FNDOBJ_B
FNDOBJ_A:
         MOV   AL,CH
         CALL  CKOBJ
         JNZ   FNDOBJ_C
         DEC   ROOM
         JNZ   FNDOBJ_A
         MOV   AL,0
FNDOBJ_B:
         MOV   ROOM,CL
         ENABLE
         POP   CX
         TEST  AL,0FFH
         RET
FNDOBJ_C:
         MOV   AL,ROOM
         JMP   SHORT FNDOBJ_B
FNDOBJ   ENDP

;********************************************************************
;
;  CKOBJ  - TEST IF AN OBJECT IS IN THE CURRENT ROOM
;
;           INPUT:  AL = OBJECT TO FIND
;           OUTPUT: AL = STATUS OF REQUEST (ZERO FLAG SET)
;                        IF = 00 THEN OBJECT NOT FOUND
;                        IF > 00 THEN OBJECT FOUND
;
;********************************************************************

CKOBJ    PROC
         PUSH  BX
         CALL  PNTRM1
CKOBJ_A:
         TEST  BYTE PTR [BX],0FFH
         JZ    CKOBJ_B
         INC   BX
         CMP   AL,[BX-1]
         JNE   CKOBJ_A
         JMP   SHORT CKOBJ_C
CKOBJ_B:
         MOV   AL,0
CKOBJ_C:
         POP   BX
         TEST  AL,0FFH
         RET
CKOBJ    ENDP

;********************************************************************
;
;  CHGOBJ - CHANGE AN OBJECT IN THE CURRENT ROOM
;
;           INPUT:  AL = OBJECT TO FIND
;                   AH = REPLACEMENT OBJECT
;           OUTPUT: NONE
;
;********************************************************************

CHGOBJ   PROC
         PUSH  BX
         CMP   AH,0
         JE    CHGOBJ_C
         CALL  PNTRM1
CHGOBJ_A:
         TEST  BYTE PTR [BX],0FFH
         JZ    CHGOBJ_B
         INC   BX
         CMP   AL,[BX-1]
         JNE   CHGOBJ_A
         MOV   [BX-1],AH
CHGOBJ_B:
         POP   BX
         RET
CHGOBJ_C:
         PUSH  AX
         CALL  GETOBJ
         POP   AX
         JMP   SHORT CHGOBJ_B
CHGOBJ   ENDP

;********************************************************************
;
;  MAKVIS - MAKE AN OBJECT VISIBLE IN THE CURRENT ROOM
;
;           INPUT:  AL = OBJECT TO FIND (WITH INV BIT SET)
;           OUTPUT: NONE
;
;********************************************************************

MAKVIS   PROC
         PUSH  BX
         CALL  PNTRM1
MAKVIS_A:
         TEST  BYTE PTR [BX],0FFH
         JZ    MAKVIS_B
         INC   BX
         CMP   AL,[BX-1]
         JNE   MAKVIS_A
         AND   AL,07FH
         MOV   [BX-1],AL
MAKVIS_B:
         POP   BX
         RET
MAKVIS   ENDP

;********************************************************************
;
;  PNTRM1 - SET BX REG TO POINT TO AN ENTRY IN A TABLE BASED ON
;           THE CURRENT ROOM.  ENTRY "PNTRM1" IS FOR THE ROOM
;           OBJECT TABLE AND ENTRY "PNTRM2" IS FOR THE ROOM OVERLAY
;           TABLE
;
;           INPUT:  NONE
;           OUTPUT: BX = FIRST BYTE FOR ROOM ENTRY IN THE SELECTED
;                        TABLE (OBJECT OR OVERLAY)
;
;********************************************************************

PNTRM1   PROC
         PUSH  AX
         LEA   BX,RMOBT1
PNTRM1_A:
         MOV   AH,ROOM
PNTRM1_B:
         DEC   AH
         JZ    PNTRM1_D
PNTRM1_C:
         INC   BX
         TEST  BYTE PTR [BX-1],0FFH
         JNZ   PNTRM1_C
         JMP   SHORT PNTRM1_B
PNTRM1_D:
         POP   AX
         RET

PNTRM2:
         PUSH  AX
         LEA   BX,SCRIND
         JMP   SHORT PNTRM1_A
PNTRM1   ENDP

;********************************************************************
;
;  SCNKEY - EXTRACT VERB AND NOUN FROM "KEYBUF" AND SEARCH THE
;           VERB/NOUN TABLES ATTEMPTING TO ASSIGN VERB/NOUN NUMBERS
;
;           INPUT:  NONE
;           OUTPUT: "VERB" CONTAINS VERB, "VERBNO" CONTAINS NUMBER
;                   "NOUN" CONTAINS NOUN, "NOUNNO" CONTAINS NUMBER
;
;********************************************************************

SCNKEY   PROC
         PUSH  AX
         PUSH  BX
         PUSH  SI
         PUSH  DI
         LEA   BX,VERB
         MOV   SI,BX
         MOV   AH,MAXWRD*2-1
         MOV   AL,' '
         MOV   [SI],AL
         INC   SI
         CALL  MOVE
         MOV   SI,BX
         LEA   BX,KEYBUF
         MOV   AH,MAXWRD
SCNKEY_A:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    SCNKEY_E
         CMP   AL,' '
         JE    SCNKEY_B
         MOV   [SI],AL
         INC   SI
         DEC   AH
         JNZ   SCNKEY_A
SCNKEY_F:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    SCNKEY_E
         CMP   AL,' '
         JNE   SCNKEY_F
SCNKEY_B:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    SCNKEY_E
         CMP   AL,' '
         JE    SCNKEY_B
         DEC   BX
         LEA   SI,NOUN
         MOV   AH,MAXWRD
SCNKEY_D:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    SCNKEY_E
         CMP   AL,' '
         JE    SCNKEY_E
         MOV   [SI],AL
         INC   SI
         DEC   AH
         JNZ   SCNKEY_D
SCNKEY_E:
         MOV   VERBNO,0
         MOV   NOUNNO,0
         CALL  CVTCAP
         LEA   BX,VERBTB
         LEA   DI,VERBNO
         LEA   SI,VERB
         CALL  SCNTBL
         LEA   BX,NOUNTB
         LEA   DI,NOUNNO
         LEA   SI,NOUN
         CALL  SCNTBL
         POP   DI
         POP   SI
         POP   BX
         POP   AX
         RET
SCNKEY   ENDP

;********************************************************************
;
;  SCNTBL - SCANS TABLE FOR VERB OR NOUN AND RETURNS ASSOCIATED
;           VERB/NOUN NUMBER
;
;           INPUT:  BX = POINTER TO TABLE TO SEARCH
;                   DI = POINTER TO STORAGE FOR VERB/NOUN NUMBER
;                   SI = POINTER TO KEYBOARD INPUT TO SCAN ON
;           OUTPUT: CONTENTS OF 'DI' REG ARE ASSIGNED VERB/NOUN #
;
;********************************************************************

SCNTBL   PROC
         PUSH  AX
         PUSH  BX
         PUSH  DI
SCNTBL_A:
         PUSH  SI
         MOV   AH,MAXWRD
SCNTBL_B:
         MOV   AL,[BX]
         INC   BX
         CMP   AL,0
         JE    SCNTBL_C
         INC   SI
         CMP   AL,[SI-1]
         JNE   SCNTBL_D
         DEC   AH
         JNE   SCNTBL_B
         MOV   AL,[BX]
         MOV   [DI],AL
SCNTBL_C:
         POP   SI
         POP   DI
         POP   BX
         POP   AX
         RET
SCNTBL_D:
         INC   BX
         DEC   AH
         JNZ   SCNTBL_D
         POP   SI
         JMP   SHORT SCNTBL_A
SCNTBL   ENDP

;********************************************************************
;
;  DELAY  - DISPLAY STRING THEN DELAY
;
;           INPUT:  BX = POINTER TO STRING TO DISPLAY
;           OUTPUT: NONE
;
;********************************************************************

DELAY    PROC
         PUSH  AX
         PUSH  BX
         CALL  DISPLY
         MOV   BX,0
         MOV   AH,5
DELAY_A:
         DEC   BX
         JNE   DELAY_A
         DEC   AH
         JNE   DELAY_A
         POP   BX
         POP   AX
         RET
DELAY    ENDP

;********************************************************************
;
;  GIVOBJ - GIVE AN OBJECT TO PLAYERS INVENTORY
;
;           INPUT:  AL = OBJECT TO BE PLACED IN INVENTORY
;           OUTPUT: NONE
;
;********************************************************************

GIVOBJ   PROC
         PUSH  AX                 ;SAVE REGISTERS
         PUSH  BX
         LEA   BX,OBJECT
         MOV   AH,MAXOBJ1
GIVOBJ_A:
         TEST  BYTE PTR [BX],0FFH
         JZ    GIVOBJ_B
         INC   BX
         DEC   AH
         JNZ   GIVOBJ_A
         JMP   SHORT GIVOBJ_C
GIVOBJ_B:
         MOV   [BX],AL
         TEST  AL,0FFH
         JZ    GIVOBJ_C
         INC   OBJCNT
GIVOBJ_C:
         POP   BX
         POP   AX
         RET
GIVOBJ   ENDP

;********************************************************************
;
;  LOCOBJ - LOCATE OBJECT EITHER IN INVENTORY OR CURRENT ROOM
;
;           INPUT:  AL = OBJECT TO BE LOCATED
;           OUTPUT: ZERO FLAG SET AS RETURN CODE
;                   IF ZF SET THEN OBJECT NOT FOUND
;
;********************************************************************

LOCOBJ   PROC
         PUSH  AX
         MOV   AH,AL
         CALL  HAVOBJ
         JNZ   LOCOBJ_A
         MOV   AL,AH
         CALL  CKOBJ
LOCOBJ_A:
         POP   AX
         RET
LOCOBJ   ENDP

;********************************************************************
;
;  CVTCAP - CONVERT INPUT VERB/NOUN TO ALL UPPER CASE LETTERS
;
;           INPUT:  NONE
;           OUTPUT: "VERB" & "NOUN" ARE CONVERTED TO ALL CAPS
;
;********************************************************************

CVTCAP   PROC
         PUSH  AX
         PUSH  BX
         LEA   BX,VERB
         MOV   AH,MAXWRD*2
CVTCAP_A:
         MOV   AL,[BX]
         CMP   AL,61H             ;LOWER CASE "A"
         JB    CVTCAP_B
         CMP   AL,7AH             ;LOWER CASE "Z"
         JA    CVTCAP_B
         SUB   AL,32              ;CONVERT TO UPPER CASE
         MOV   [BX],AL
CVTCAP_B:
         INC   BX
         DEC   AH
         JNZ   CVTCAP_A
         POP   BX
         POP   AX
         RET
CVTCAP   ENDP

;********************************************************************
;
;  MOVE   - GENERAL PURPOSE STRING MOVE
;
;           INPUT:  BX = PNTR TO SOURCE STRING
;                   SI = PNTR TO DEST STRING
;                   AH = NUMBER OF BYTES TO MOVE
;           OUTPUT: NONE
;
;********************************************************************

MOVE     PROC
         PUSH  AX
         PUSH  BX
         PUSH  SI
MOVE_A:
         MOV   AL,[BX]
         MOV   [SI],AL
         INC   BX
         INC   SI
         DEC   AH
         JNE   MOVE_A
         POP   SI
         POP   BX
         POP   AX
         RET
MOVE     ENDP

;********************************************************************
;
;  ASCLNO - CONVERT BINARY NUMBER TO ASCII STRING
;
;           INPUT:  BX = NUMBER TO CONVERT
;                   SI = PNTR TO DEST STRING
;           OUTPUT: [SI] CONTAINS 5 BYTE ASCII STRING
;
;********************************************************************

ASCLNO   PROC
         PUSH  AX
         PUSH  BX
         PUSH  SI
         MOV   ASCSAV,BX
         LEA   BX,TENTBL
ASCLNO_A:
         MOV   BYTE PTR [SI],'0'
         MOV   AX,ASCSAV
ASCLNO_B:
         SUB   AX,[BX]
         JS    ASCLNO_C
         INC   BYTE PTR [SI]
         MOV   ASCSAV,AX
         JMP   SHORT ASCLNO_B
ASCLNO_C:
         INC   SI
         ADD   BX,2
         MOV   AX,[BX]
         CMP   AX,0
         JNE   ASCLNO_A
         POP   SI
         POP   BX
         POP   AX
         RET
ASCLNO   ENDP

;********************************************************************
;
;  CKDRAW - CHECK TO SEE IF SCREEN NEEDS TO BE RE-DRAWN
;
;           INPUT:  AL = OBJECT BEING CHANGED IN ROOM
;           OUTPUT: NONE
;
;********************************************************************

CKDRAW   PROC
         PUSH  AX
         PUSH  BX
         MOV   AH,AL
         CALL  INDARK
         JE    CKDRAW_C
         MOV   AL,AH
         LEA   BX,MOVOBJ
CKDRAW_A:
         TEST  BYTE PTR [BX],0FFH
         JE    CKDRAW_C
         INC   BX
         CMP   AL,[BX-1]
         JNE   CKDRAW_D
CKDRAW_F:
         INC   BX
         TEST  BYTE PTR [BX-1],0FFH
         JNZ   CKDRAW_F
CKDRAW_B:
         MOV   AH,[BX]
         INC   BX
         CMP   AH,0
         JE    CKDRAW_A
         CMP   AH,ROOM
         JNE   CKDRAW_B
         CALL  DRAWSC
CKDRAW_C:
         POP   BX
         POP   AX
         RET
CKDRAW_D:
         INC   BX
         TEST  BYTE PTR [BX-1],0FFH
         JNZ   CKDRAW_D
CKDRAW_E:
         INC   BX
         TEST  BYTE PTR [BX-1],0FFH
         JNE   CKDRAW_E
         JMP   SHORT CKDRAW_A
CKDRAW   ENDP

;********************************************************************
;
;  DRAWSC - RE-DRAW THE GRAPHIC SCREEN
;
;           INPUT:  NONE
;           OUTPUT: NONE
;
;********************************************************************

DRAWSC   PROC
         PUSH  AX
         PUSH  BX
         PUSH  SI
         CALL  PNTRM2
         MOV   AL,[BX]
         DEC   AL
         SHL   AL,1
         MOV   AH,0
         LEA   BX,SCRTAB
         ADD   BX,AX
         MOV   SI,[BX]
         DISABLE
         CALL  SHOSCR
         CALL  SHOOBJ
         ENABLE
         POP   SI
         POP   BX
         POP   AX
         RET
DRAWSC   ENDP

CODE     ENDS
         END

;        END FILE = ADVUTIL/ASM
